﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.Threading;
using Sinacor.Infra.UI.Controls.SmartClient;
using PSE.Framework.Configuration;
using PSE.Framework.Common.Security.Services.Configuration;
 
namespace Sinacor.Infra.UI.Desktop.SmartClient
{
    public class ActivityMonitor : DispatcherObject, IDisposable
    {
        private static Mutex mtx = new Mutex();
        private static ActivityMonitor _activityMonitor;
        private static AutoResetEvent autoEvent = new AutoResetEvent(false);

        private WindowManager _windowManager;

        private int _timeToWaitActivity = 15; // Minutos
        private bool _stillRunning = false;
        private bool _isActive = true;
        private Thread thr = null;

        private const string SERVICES_CONFIGURATION_SECTION_NAME = "servicesConfiguration";

        public bool IsActive
        {
            get { return _isActive; }
            set { _isActive = value; }
        }

        public int TimeToWaitActivity
        {
            get { return _timeToWaitActivity; }
            set { _timeToWaitActivity = value; }
        }

        protected ActivityMonitor()
        {
            _windowManager = WindowManager.GetInstance();
            _windowManager.OnWindowActivity += new WindowManager.OnWindowActivityDelegate(_windowManager_OnWindowActivity);

            ApplicationConfiguration config = ApplicationConfiguration.GetCurrent();

            _timeToWaitActivity = config.GetSection<ServicesConfigurationSection>(SERVICES_CONFIGURATION_SECTION_NAME).ChannelTimeout;

            this.Start();
        }

        public void Start()
        {
            thr = new Thread(new ThreadStart(InactivityTimeControl));
            _stillRunning = true;
            thr.Start();
        }

        public static ActivityMonitor GetInstance()
        {
            mtx.WaitOne();
            if (_activityMonitor == null)
                _activityMonitor = new ActivityMonitor();
            mtx.ReleaseMutex();
            return _activityMonitor;
        }

        private void InactivityTimeControl()
        {
            int TIME_TO_WAIT_EVENT = _timeToWaitActivity * 60 * 1000;

            _stillRunning = true;
            while (_stillRunning)
            {
                if (autoEvent.WaitOne(TIME_TO_WAIT_EVENT, false))
                {
                    IsActive = true;
                }
                else
                {
                    if (IsActive == true)
                    {
                        IsActive = false;
                        WindowManager.GetInstance().NotifyApplicationInactivity();
                    }
                }
            }
        }

        /// <summary>
        /// Método que trata o evento WindowActivity inicializando o tempo de esperado
        /// do ActivityMonitor
        /// </summary>
        //private void _windowManager_OnWindowActivity(SinacorWindow sinacorwindow)
        private void _windowManager_OnWindowActivity()
        {
            InitializeWaitingTime();
        }

        private void InitializeWaitingTime()
        {
            autoEvent.Set();
            /*
            _isActive = true;
            _timeToNotifyInactivity = TIME_TO_WAIT_ACTIVITY * 60 * 1000; //Cálculo em Milisegundos
             */
        }

        public void Pause()
        {
            _stillRunning = false;
            autoEvent.Set();
            autoEvent.Reset();
        }



        #region IDisposable Members
        public void Dispose()
        {
            _stillRunning = false;
            IsActive = false;
            autoEvent.Set();
            try { thr.Abort(); }
            catch { }
        }
        #endregion
    }
}
